from django.shortcuts import render

# Create your views here.
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from rest_framework.decorators import api_view
from django.views import View
from .models import Couse
from .serializers import CouseSerializer
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from rest_framework import generics

# 使用Django的信号机制生成Token
from django.db.models.signals import post_save  # 保存之后，即用户已经建好之后的信号
from django.conf import settings
from django.dispatch import receiver  # 接收信号
from rest_framework.authtoken.models import Token

from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import BasicAuthentication, SessionAuthentication, TokenAuthentication
from .permission import IsOwnerReadOnly


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def generate_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)


course_dict = {
    'name': '课程名称',
    'introduction': '课程介绍',
    'price': 0.11
}


@csrf_exempt
def course_list(request):
    if request.method == 'GET':
        return JsonResponse(course_dict)
    if request.method == 'POST':
        data = json.loads(request.body.decode('utf-8'))
        return JsonResponse(data)


# @method_decorator(csrf_exempt, name='dispatch')
# class CourseList(View):
#     def get(self, request):
#         return JsonResponse(course_dict)
#
#     def post(self, request):
#         course = json.loads(request.body.decode('utf-8'))
#         return JsonResponse(course,safe=False)  # 如果解析的数据不是字典类型，是字符串的话，需要使用safe=false

@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def couse_list(request):
    if request.method == 'GET':
        s = CouseSerializer(instance=Couse.objects.all(), many=True)
        return Response(data=s.data, status=status.HTTP_200_OK)
    elif request.method == 'POST':
        s = CouseSerializer(data=request.data, partial=True)
        if s.is_valid():
            s.save(teacher=request.user)
            return Response(data=s.data, status=status.HTTP_201_CREATED)
        return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(["GET", "PUT", "DELETE"])
@authentication_classes([TokenAuthentication])
def course_detail(request, pk):  # 通过url传递pk
    """
    获取、更新、删除一个课程
    :param request:
    :param pk:
    :return:
    """
    try:
        course = Couse.objects.get(pk=pk)
    except Couse.DoesNotExist:
        return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
    else:
        if request.method == "GET":
            s = CouseSerializer(instance=course)  # 序列化一个对象不需要many=True
            return Response(data=s.data, status=status.HTTP_200_OK)

        elif request.method == "PUT":  # PUT方法表示更新，部分写法和POST方法类似
            s = CouseSerializer(instance=course, data=request.data)  # instance是指要序列化哪个实例，data表示数据哪里来的
            # 表示把data的数据，反序列化之后，保存或者更新到cuorse对象里
            if s.is_valid():
                s.save()  # 不需要teacher字段
                return Response(s.data, status=status.HTTP_200_OK)

        elif request.method == "DELETE":
            course.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)


class CourseList(APIView):
    authentication_classes = [TokenAuthentication]

    def get(self, request):
        queryset = Couse.objects.all()
        s = CouseSerializer(instance=queryset, many=True)
        return Response(data=s.data, status=status.HTTP_200_OK)

    def post(self, request):
        s = CouseSerializer(data=request.data, partial=True)
        if s.is_valid():
            s.save(teacher=self.request.user)
            return Response(data=s.data, status=status.HTTP_201_CREATED)
        return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)


class CourseDetail(APIView):
    @staticmethod
    def get_object(pk):
        try:
            return Couse.objects.get(pk=pk)
        except Couse.DoesNotExist:
            return

    def get(self, request, pk):
        obj = self.get_object(pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        s = CouseSerializer(instance=obj)
        return Response(data=s.data, status=status.HTTP_200_OK)

    # 更新课程的信息
    def put(self, request, pk):
        obj = self.get_object(pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        s = CouseSerializer(instance=obj, data=request.data)
        if s.is_valid():
            s.save()
            return Response(data=s.data, status=status.HTTP_200_OK)
        return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        obj = self.get_object(pk=pk)
        if not obj:
            return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


# 通用类视图 GenericAPIView
from rest_framework import mixins
from rest_framework.generics import GenericAPIView


class GCourseList(generics.ListCreateAPIView):
    queryset = Couse.objects.all()
    serializer_class = CouseSerializer

    # permission_classes = [IsAuthenticated, IsOwnerReadOnly]

    def perform_create(self, serializer):
        serializer.save(teacher=self.request.user)


class GCourseDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Couse.objects.all()
    serializer_class = CouseSerializer
    permission_classes = [IsAuthenticated, IsOwnerReadOnly]


# DRF的视图集viewset
from rest_framework import viewsets


class CourseViewSet(viewsets.ModelViewSet):
    queryset = Couse.objects.all()
    serializer_class = CouseSerializer
    permission_classes = [IsAuthenticated, IsOwnerReadOnly]

    def perform_create(self, serializer):
        serializer.save(teacher=self.request.user)
